package com.xy.work.template.base.component.impl;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.PutObjectResult;
import com.xy.work.template.base.component.FileService;
import com.xy.work.template.base.domain.UploadResult;
import com.xy.work.template.common.enums.CommonCodeEnum;
import com.xy.work.template.common.exception.BaseCustomException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
/**
 * @author niuniu
 * @Date: 2021/5/15 09:38
 * @Description: 完成上传文件相关操作
 */
@Service
@Slf4j
public class FileServiceImpl implements FileService {
    @Override
    public UploadResult uploadImg(MultipartFile file, String rootPath, String bucketName, String endpoint, String accessKeyId, String accessKeySecret) {
        String imgConfig ="bmp,jpg,png,webp,jpeg";
        return  upload(file, imgConfig.toLowerCase().split(","),rootPath,bucketName,endpoint,accessKeyId,accessKeySecret);
    }

    @Override
    public UploadResult upload(MultipartFile file, String[] extensionConfig, String rootPath, String bucketName, String endpoint, String accessKeyId, String accessKeySecret) {
        UploadResult UploadResult=null;
        OSS ossClient=null;
        try {
            if(ObjectUtil.isEmpty(file)){
                throw new BaseCustomException(CommonCodeEnum.UPLOAD_FILE_NOT_EXIST);
            }
            //获取原生文件名  xxx.jpg
            String originalFileName = file.getOriginalFilename();
            //JDK8的日期格式
            LocalDateTime ldt = LocalDateTime.now();
            DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy/MM/dd");
            //拼装路径,oss上存储的路径  user/2022/12/1/sdfdsafsdfdsf.jpg
            String folder = dtf.format(ldt);
            String fileName = IdUtil.simpleUUID();
            String extension = FileUtil.extName(originalFileName);
            if(StrUtil.isEmpty(extension)){
                throw new BaseCustomException(CommonCodeEnum.UPLOAD_FILE_EXTENSION_NOT_EXIST);
            }
            if(!ArrayUtil.contains(extensionConfig,extension.toLowerCase())){
                throw new BaseCustomException(CommonCodeEnum.UPLOAD_FILE_FORMAT_ERROR);
            }
            // 在OSS上的bucket下创建 user 这个文件夹
            if(!rootPath.endsWith("/")){
                rootPath = rootPath+"/";
            }
            ossClient = getOssClient(endpoint,accessKeyId,accessKeySecret);
            String newFileName = rootPath+folder+"/"+fileName+"."+extension;
            PutObjectResult putObjectResult = ossClient.putObject(bucketName,newFileName,file.getInputStream());
            //拼装返回路径
            if(putObjectResult != null){
                UploadResult= new UploadResult();
                if(!newFileName.startsWith("/")){
                    newFileName="/"+newFileName;
                }
                UploadResult.setSavePath(newFileName);
                UploadResult.setUrl("https://"+bucketName+"."+endpoint+UploadResult.getSavePath());
            }
        }catch (IOException e) {
            log.error("文件上传失败",e);
        }catch (BaseCustomException e) {
            log.error("文件上传验证不通过",e);
        } finally {
            //oss关闭服务，不然会造成OOM
            if(ObjectUtil.isNotNull(ossClient)){
                ossClient.shutdown();
            }
        }
        if(ObjectUtil.isNotNull(UploadResult)){
            log.info("上传文件结果：{}",UploadResult);
        }
        return UploadResult;
    }

    @Override
    public OSS getOssClient(String endpoint, String accessKeyId, String accessKeySecret) {
        if(StrUtil.isEmpty(endpoint)){
            throw new BaseCustomException(CommonCodeEnum.OSS_ENDPOINT_ERROR);
        }
        if(StrUtil.isEmpty(accessKeyId)){
            throw new BaseCustomException(CommonCodeEnum.OSS_ACCESS_KEY_ID_ERROR);
        }
        if(StrUtil.isEmpty(accessKeySecret)){
            throw new BaseCustomException(CommonCodeEnum.OSS_ACCESS_KEY_SECRET_ERROR);
        }
        return new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
    }
}
